home *** CD-ROM | disk | FTP | other *** search
/ Aminet 48 / Aminet 48 (2002)(GTI - Schatztruhe)[!][Apr 2002].iso / Aminet / docs / misc / MemManual.lha / MemManual / C_Sources / SwapTest.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-11-17  |  9.8 KB  |  258 lines

  1. /*************************************************
  2.  ** 68040/68060 Swap test                       **
  3.  ** © 2001 THOR-Software                        **
  4.  ** 17.11.2001 by Thomas Richter                **
  5.  *************************************************/
  6.  
  7. /// Includes
  8. #include <exec/types.h>
  9. #include <exec/nodes.h>
  10. #include <exec/lists.h>
  11. #include <exec/ports.h>
  12. #include <exec/memory.h>
  13. #include <exec/execbase.h>
  14.  
  15. #include <dos/dos.h>
  16.  
  17. #include <mmu/mmutags.h>
  18. #include <mmu/context.h>
  19. #include <mmu/exceptions.h>
  20.  
  21. #include <proto/exec.h>
  22. #include <proto/mmu.h>
  23. #include <proto/dos.h>
  24.  
  25. #include <m68881.h>
  26. ///
  27. /// Defines
  28. ///
  29. /// Statics
  30. char version[]="$VER: SwapTest 1.00 (17.11.2001) © THOR";
  31.  
  32. struct ExecBase *SysBase;
  33. struct DosLibrary *DOSBase;
  34. struct MMUBase *MMUBase;
  35.  
  36. ULONG props1,props2;
  37. UBYTE *spare;
  38. UBYTE *phys1,*phys2;
  39.  
  40. ULONG pagesize;
  41.  
  42. BOOL segfault;
  43. ///
  44. /// Protos
  45. long __saveds main(void);
  46. long RunSwapTest(void);
  47. int __asm __saveds __interrupt SwapFunction(register __a0 struct ExceptionData *exd);
  48. int __asm __saveds __interrupt ExceptFunction(register __a0 struct ExceptionData *exd);
  49. double CalcSin(double *x);
  50. void End(void);
  51. BOOL SwapIn(struct MMUContext *ctx,APTR fault);
  52. ///
  53.  
  54. /// main
  55. long __saveds main(void)
  56. {
  57. long rc = 25;
  58.  
  59.         SysBase = *(struct ExecBase **)(4L);
  60.  
  61.         if (DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",37)) {
  62.                 if (MMUBase = (struct MMUBase *)OpenLibrary("mmu.library",43)) {
  63.  
  64.                         /*
  65.                         if (SysBase->AttnFlags & (AFF_68040|AFF_68040)) {
  66.                                 rc = RunSwapTest();
  67.                         } else {
  68.                                 Printf("This program requires an 68040 or 68060\n"
  69.                                        "or, at least, makes little sense for any\n"
  70.                                        "other processor of the MC68K series.\n");
  71.                                 rc = 5;
  72.                         }       
  73.                         */
  74.  
  75.                         rc = RunSwapTest();
  76.  
  77.                         if (rc > 64) {
  78.                                 PrintFault(rc,"SwapTest failed");
  79.                                 rc = 10;
  80.                         }
  81.                         CloseLibrary((struct Library *)MMUBase);
  82.                 } else {
  83.                         Printf("SwapTest requires V43 of the mmu.library.\n");
  84.                 }
  85.                 CloseLibrary((struct Library *)DOSBase);
  86.         }
  87.  
  88.         return rc;
  89. }
  90. ///
  91. /// RunSwapTest
  92. long RunSwapTest(void)
  93. {
  94. long rc = ERROR_NO_FREE_STORE;
  95. struct MMUContext *ctx;
  96. struct ExceptionHook *swaphook,*excepthook;
  97. ULONG size;
  98.  
  99.         ctx = CurrentContext(NULL);
  100.         pagesize = GetPageSize(ctx);
  101.         spare = AllocAligned(pagesize<<1,MEMF_PUBLIC|MEMF_CLEAR,pagesize);
  102.         if (spare == NULL)
  103.                 return ERROR_NO_FREE_STORE;
  104.  
  105.         phys1   = spare;
  106.         size    = pagesize;
  107.         props1  = PhysicalLocation(ctx,(void **)&phys1,&size);
  108.         if (size != pagesize) {
  109.                 Printf("Unsupported system memory mapping.\n");
  110.                 FreeMem(spare,pagesize<<1);
  111.                 return 10;
  112.         }
  113.  
  114.         phys2   = spare + pagesize;
  115.         size    = pagesize;
  116.         props2  = PhysicalLocation(ctx,(void **)&phys2,&size);
  117.         if (size != pagesize) {
  118.                 Printf("Unsupported system memory mapping.\n");
  119.                 FreeMem(spare,pagesize<<1);
  120.                 return 10;
  121.         }
  122.  
  123.         segfault = 2;
  124.  
  125.         if (EnterMMUContext(ctx,FindTask(NULL))) {
  126.                 swaphook = AddContextHook(MADTAG_CONTEXT,ctx,
  127.                                           MADTAG_TASK,FindTask(NULL),
  128.                                           MADTAG_TYPE,MMUEH_SWAPPED,
  129.                                           MADTAG_CODE,&SwapFunction,
  130.                                           MADTAG_PRI,100,
  131.                                           TAG_DONE);
  132.                 if (swaphook) {
  133.                         excepthook = AddContextHook(MADTAG_CONTEXT,NULL,
  134.                                                     MADTAG_TASK,FindTask(NULL),
  135.                                                     MADTAG_TYPE,MMUEH_SEGFAULT,
  136.                                                     MADTAG_CODE,&ExceptFunction,
  137.                                                     MADTAG_PRI,100,
  138.                                                     TAG_DONE);
  139.                         if (excepthook) {
  140.                                 struct MinList *proplist;
  141.                                 LockMMUContext(ctx);
  142.  
  143.                                 proplist = GetMapping(ctx);
  144.                                 if (proplist) {
  145.                                         if (SetProperties(ctx,MAPP_SWAPPED|MAPP_SINGLEPAGE,~0,(ULONG)spare,pagesize<<1,MAPTAG_BLOCKID,0,TAG_DONE)) {
  146.                                                 if (RebuildTree(ctx)) {
  147.                                                                 ActivateException(swaphook);
  148.                                                                 ActivateException(excepthook);
  149.  
  150.                                                                 /*
  151.                                                                  * trigger the exception!
  152.                                                                  */
  153.                                                                 CalcSin((double *)spare);
  154.  
  155.                                                                 if (segfault) {
  156.                                                                         Printf("Your 68040 or 68060.library does not support virtual memory correctly.\n");
  157.                                                                 } else {
  158.                                                                         double tmp = 0.0;
  159.                                                                         UBYTE *start,*end;
  160.                                                                         UBYTE *func;
  161.  
  162.                                                                         Printf("Your 68040 or 68060.library handles virtual memory correctly on data swaps.\n");
  163.  
  164.                                                                         start = (UBYTE *)(&CalcSin);
  165.                                                                         end   = (UBYTE *)(&End);
  166.  
  167.                                                                         func = spare + pagesize-4;
  168.                                                                         CopyMem(start,func,end-start);
  169.                                                                         CacheClearU();
  170.  
  171.                                                                         SetPageProperties(ctx,MAPP_SWAPPED|MAPP_SINGLEPAGE,~0,(ULONG)spare,MAPTAG_BLOCKID,0,TAG_DONE);
  172.                                                                         SetPageProperties(ctx,MAPP_SWAPPED|MAPP_SINGLEPAGE,~0,((ULONG)spare) + pagesize,MAPTAG_BLOCKID,0,TAG_DONE);
  173.  
  174.                                                                         segfault = 2;
  175.  
  176.                                                                         (*(double (*)(double *))func)(&tmp);
  177.  
  178.                                                                         if (segfault) {
  179.                                                                                 Printf("Your 68040 or 68060.library does not support virtual memory correctly.\n");
  180.                                                                         } else {
  181.                                                                                 Printf("Your 68040 or 68060.library handles virtual memory correctly on instruction swaps.\n");
  182.                                                                         }
  183.                                                                 }
  184.  
  185.                                                                 DeactivateException(excepthook);
  186.                                                                 DeactivateException(swaphook);
  187.  
  188.                                                                 rc = 0;
  189.  
  190.                                                 }
  191.                                                 SetPropertiesMapping(ctx,proplist,(ULONG)spare,pagesize<<1,~0);
  192.                                                 RebuildTree(ctx);
  193.                                         }
  194.                                         ReleaseMapping(ctx,proplist);
  195.                                 }
  196.  
  197.                                 UnlockMMUContext(ctx);
  198.                                 RemContextHook(excepthook);
  199.                         }
  200.                         RemContextHook(swaphook);
  201.                 }
  202.  
  203.  
  204.                 LeaveMMUContext(FindTask(NULL));
  205.         }
  206.         FreeMem(spare,pagesize<<1);
  207.  
  208.         return rc;
  209. }
  210. ///
  211. /// SwapIn
  212. BOOL SwapIn(struct MMUContext *ctx,APTR fault)
  213. {
  214. UBYTE *base;
  215.  
  216.         base = (UBYTE *)((ULONG)(fault) & (ULONG)(-(LONG)pagesize));
  217.         if (base == spare) {
  218.                 return SetPageProperties(ctx,props1,~0,(ULONG)base,MAPTAG_DESTINATION,phys1,TAG_DONE);
  219.         } else if (base == spare + pagesize) {
  220.                 return SetPageProperties(ctx,props2,~0,(ULONG)base,MAPTAG_DESTINATION,phys2,TAG_DONE);
  221.         }
  222.         return FALSE;
  223. }
  224. ///
  225. /// SwapFunction
  226. int __asm __saveds __interrupt SwapFunction(register __a0 struct ExceptionData *exd)
  227. {
  228.         if (SwapIn(exd->exd_Context,exd->exd_FaultAddress) | SwapIn(exd->exd_Context,exd->exd_NextFaultAddress)) {
  229.                 segfault = FALSE;
  230.                 return 0;
  231.         }
  232.         return 1;
  233. }
  234. ///
  235. /// ExceptFunction
  236. int __asm __saveds __interrupt ExceptFunction(register __a0 struct ExceptionData *exd)
  237. {
  238.         if (SwapIn(exd->exd_Context,exd->exd_FaultAddress) | SwapIn(exd->exd_Context,exd->exd_NextFaultAddress)) {
  239.                 segfault = FALSE;
  240.                 return 0;
  241.         }
  242.         return 1;
  243. }
  244. ///
  245. /// CalcSin
  246. double CalcSin(double *x)
  247. {
  248.         return sin(x[1]);
  249. }
  250. ///
  251. /// end marker
  252. void End(void)
  253. {
  254. }
  255. ///
  256.  
  257.  
  258.